
/*
 * Copyright (C) 2010-2015 Alibaba Group Holding Limited
 */


#ifndef _NGX_HTTP_TFS_RC_SERVER_INFO_H_INCLUDED_
#define _NGX_HTTP_TFS_RC_SERVER_INFO_H_INCLUDED_


#include <ngx_core.h>
#include <ngx_config.h>
#include <ngx_http.h>
#include <ngx_tfs_common.h>
#include <ngx_http_tfs_tair_helper.h>


#define ngx_http_tfs_get_cluster_id(cluster_id_data) (cluster_id_data[1] - '0')


typedef struct
{
    int32_t             group_seq; /* get from ns */
    ngx_str_t           ns_vip_text;
    ngx_http_tfs_inet_t ns_vip;
} ngx_http_tfs_group_info_t;


typedef struct
{
    uint32_t                  cluster_id;
    int32_t                   group_count; /* get from ns */
    uint32_t                  info_count;
    ngx_http_tfs_group_info_t group_info[NGX_HTTP_TFS_MAX_CLUSTER_ID_COUNT];
} ngx_http_tfs_cluster_group_info_t;


typedef struct
{
    uint32_t            cluster_stat;
    uint32_t            access_type;
    uint32_t            cluster_id; /* get from ns */
    ngx_str_t           cluster_id_text;
    ngx_str_t           ns_vip_text;
    ngx_http_tfs_inet_t ns_vip;
} ngx_http_tfs_physical_cluster_t;


typedef struct
{
    uint8_t                              need_duplicate;
    uint32_t                             dup_server_addr_hash;
    ngx_http_tfs_tair_server_addr_info_t dup_server_info;

    /* for read and write */
    uint32_t                        rw_cluster_count;
    ngx_http_tfs_physical_cluster_t rw_clusters[NGX_HTTP_TFS_MAX_CLUSTER_COUNT];
} ngx_http_tfs_logical_cluster_t;


typedef enum
{
    NGX_HTTP_TFS_OPER_INVALID = 0,
    NGX_HTTP_TFS_OPER_READ,
    NGX_HTTP_TFS_OPER_WRITE,
    NGX_HTTP_TFS_OPER_UNLINK,
    NGX_HTTP_TFS_OPER_COUNT
} ngx_http_tfs_oper_type_e;


typedef struct
{
    ngx_http_tfs_oper_type_e oper_type;
    uint32_t                 oper_app_id;
    uint64_t                 oper_times;
    uint64_t                 oper_size;
    uint64_t                 oper_rt;
    uint64_t                 oper_succ;
} ngx_http_tfs_stat_rcs_t;


typedef struct
{
    u_char      color;
    u_char      dummy;
    ngx_queue_t queue;

    /* for keep alive, fixed sequence */
    ngx_queue_t kp_queue;

    ngx_str_t appkey;
    uint64_t  app_id;
    ngx_str_t session_id;
    uint32_t  rc_servers_count;
    uint64_t *rc_servers;

    /* logical cluster */
    uint32_t logical_cluster_count;
    ngx_http_tfs_logical_cluster_t
        logical_clusters[NGX_HTTP_TFS_MAX_CLUSTER_COUNT];

    uint8_t need_duplicate;

    uint32_t  report_interval;
    uint64_t  modify_time;
    uint64_t  meta_root_server;
    ngx_str_t remote_block_cache_info;

    ngx_http_tfs_stat_rcs_t stat_rcs[NGX_HTTP_TFS_OPER_COUNT];

    /* for unlink & update */
    uint8_t unlink_cluster_group_count; /* this ~= unlink_cluster_count get from
                                           rcs */
    ngx_http_tfs_cluster_group_info_t
        unlink_cluster_groups[NGX_HTTP_TFS_MAX_CLUSTER_COUNT];

    uint32_t use_remote_block_cache;
} ngx_http_tfs_rcs_info_t;


typedef struct
{
    ngx_rbtree_t      rbtree;
    ngx_rbtree_node_t sentinel;
    ngx_queue_t       queue;

    /* for keep alive, fixed sequence */
    ngx_queue_t kp_queue;
} ngx_http_tfs_rc_shctx_t;


typedef struct
{
    ngx_http_tfs_rc_shctx_t *sh;
    ngx_slab_pool_t         *shpool;
} ngx_http_tfs_rc_ctx_t;


ngx_int_t ngx_http_tfs_rc_server_init_zone(ngx_shm_zone_t *shm_zone,
                                           void           *data);
void      ngx_http_tfs_rc_server_expire(ngx_http_tfs_rc_ctx_t *ctx);
ngx_http_tfs_rcs_info_t *ngx_http_tfs_rcs_lookup(ngx_http_tfs_rc_ctx_t *ctx,
                                                 ngx_str_t              appkey);
void ngx_http_tfs_rc_server_destroy_node(ngx_http_tfs_rc_ctx_t   *ctx,
                                         ngx_http_tfs_rcs_info_t *rc_info_node);
void ngx_http_tfs_rcs_set_group_info_by_addr(ngx_http_tfs_rcs_info_t *rc_info,
                                             ngx_int_t           group_count,
                                             ngx_int_t           seq_id,
                                             ngx_http_tfs_inet_t addr);
void ngx_http_tfs_dump_rc_info(ngx_http_tfs_rcs_info_t *rc_info,
                               ngx_log_t               *log);
ngx_int_t ngx_http_tfs_rcs_stat_update(ngx_http_tfs_t          *t,
                                       ngx_http_tfs_rcs_info_t *rc_info,
                                       ngx_http_tfs_oper_type_e oper_type);

#endif /* _NGX_HTTP_TFS_RC_SERVER_INFO_H_INCLUDED_ */
